-module(interpreter).

-export([
    interpret/1
]).

interpret(OutSocket) -> interpret(OutSocket, 1,1,[],0).

interpret(OutSocket, QuestionNumber, OptionNumber, AnswerSet, CorrectCount) ->
    receive
        header ->
            wait_value(OutSocket),
            interpret(OutSocket,QuestionNumber,1,[],CorrectCount);
        question ->
            %if we've option numbers, then we have the possibility of answers
            %so attempt to allow the user to answer the question before presenting
            %the next question
            if
                %only do this if the option number > 1
                OptionNumber > 1 ->
                    %get the answer from the user
                    AnswerCorrect = get_answer(OutSocket,OptionNumber,AnswerSet),
                    case AnswerCorrect of
                        %if the answer is correct, increment the count
                        true ->
                            NewCorrectCount = CorrectCount + 1,
                            wait_value(OutSocket,"Question",QuestionNumber),
                            interpret(OutSocket,QuestionNumber+1,1,[],NewCorrectCount);
                        %otherwise, print next question without updating correct count
                        false ->
                            wait_value(OutSocket,"Question",QuestionNumber),
                            interpret(OutSocket,QuestionNumber+1,1,[],CorrectCount)
                    end;
                 true ->
                    wait_value(OutSocket,"Question",QuestionNumber),
                    interpret(OutSocket,QuestionNumber+1,1,[],CorrectCount)
            end;
        option ->
            wait_value(OutSocket,"   Option",OptionNumber),
            interpret(OutSocket,QuestionNumber,OptionNumber+1,AnswerSet,CorrectCount);
        answer ->
            NewAnswerSet = AnswerSet ++ [OptionNumber],
            wait_value(OutSocket,"   Option",OptionNumber),
            interpret(OutSocket,QuestionNumber,OptionNumber+1,NewAnswerSet,CorrectCount);
         done ->
            %the done token also signifies we need to ask the question again...
            if
                %only do this if the option number > 1
                OptionNumber > 1 ->
                    %get the answer from the user
                    AnswerCorrect = get_answer(OutSocket,OptionNumber,AnswerSet),
                    case AnswerCorrect of
                        %if the answer is correct, increment the count
                        true ->
                            gen_tcp:send(OutSocket,io_lib:format("Done: ~b of ~b correct!~n",[CorrectCount+1,QuestionNumber-1])),
                            gen_tcp:close(OutSocket);
                        %do not update count, and display
                        false ->
                            gen_tcp:send(OutSocket,io_lib:format("Done: ~b of ~b correct!~n",[CorrectCount,QuestionNumber-1])),
                            gen_tcp:close(OutSocket)
                    end;
                 true ->
                    gen_tcp:send(OutSocket,io_lib:format("Done: ~b of ~b correct!~n",[CorrectCount,QuestionNumber-1])),
                    gen_tcp:close(OutSocket)
            end
    end.

wait_value(OutSocket) ->
    receive
        Value ->
            gen_tcp:send(OutSocket,io_lib:format("~s~n",[Value]))
    end.

wait_value(OutSocket,Before, Number) ->
    receive
        Value ->
            gen_tcp:send(OutSocket,io_lib:format("~s #~b: ~s~n",[Before,Number,Value]))
    end.

get_answer(OutSocket,OptionNumber, AnswerSet) ->
    gen_tcp:send(OutSocket,io_lib:format("Enter Number from 1-~b: ",[OptionNumber-1])),
    case gen_tcp:recv(OutSocket, 0) of
        {ok, Value} ->
           [StrValue|_] = io_lib:format("~s",[Value]),
           [NValue|_] = StrValue,
           TermValue = NValue - 48,
           lists:member(TermValue,AnswerSet);
        _->
           gen_tcp:send(OutSocket,io_lib:format("Error during test, closing.",[]))
    end.
    

